/**
 * \file   entorno.cpp
 * \author Fabian Jesus Machado
 * \date   Septiembre de 2011
 * 
 *  Este archivo es parte del proyecto NPASM, un ensamblador para
 * microcontroladores PIC con sintaxis Intel, desarrollado inicialmente
 * por Fabian Machado (fabianjsm@gmail.com, twitter@fabianjsm).
 *  El codigo fuente esta diponible en el repositorio SVN de Google:
 *      http://npasm.googlecode.com/svn/trunk.
 * 
 * Septiembre de 2011.
 * 
 */
#include <iostream>
#include <string>
#include <stdio.h>
#include "entorno.h"
#include "auxiliar.h"
#include "tstring.h"

using namespace std;

/**
 * Constructor de la clase entorno
 */
entorno::entorno()
{
	TS = new ts();
	nfuente=0;
	yyin=0;
	m = new mm;
	TString = new tstring;
}

/**
 * Destructor de la clase entorno
 */
entorno::~entorno()
{
}

void entorno::SetSalida(string _salida)
{
	if(str_nombre_base.length())
		throw(string("redefinicion de la salida"));
	str_nombre_base = _salida;
}

void entorno::SetEntrada(string _entrada)
{
	str_entrada.push_back(_entrada);
}

void entorno::SetIncDir(string _incdir)
{
	str_incdir.push_back(_incdir);
}

void entorno::SetDefine(string _define)
{
	str_define.push_back(_define);
}

int entorno::AbrirFuente(bool reset)
{
	if(reset) {
		nfuente = 0;
		yyin = 0;
	}
	if(yyin) {
		fclose(yyin);
		++nfuente;
	};
	if(nfuente == str_entrada.size())
		return 1;
	const char *s = str_entrada[nfuente].c_str();
	yyin = fopen(s, "rb");
	if(!yyin)
		throw(mkstring("No se puede abrir '%s'", s));
	if(reset)
		yyrestart(yyin);
	Linea = 1;
	SetNombreArchivoActual(str_entrada[nfuente]);
	return 0;
}

void entorno::CerrarFuente()
{
	if(yyin)
		fclose(yyin);
}

size_t entorno::GetLinea()
{
	return Linea;
}

void entorno::SetLinea(size_t l)
{
	Linea=l;
}

void entorno::nl()
{
	++Linea;
}

size_t entorno::GetPaso()
{
	return Paso;
}

void entorno::SetPaso(size_t _paso)
{
	Paso = _paso;
}

std::string entorno::GetNombreBase()
{
	return str_nombre_base;
}

/**
 * Esta funcion crea la base de los nombres de archivos
 * Por ejemplo, cuando compilamos "../ejemplos/led.asm":
 * 
 *   str_nombre_base = "../ejemplos/led"
 *   str_dir_base    = "../ejemplos/"
 */
void entorno::Nombres()
{
	string base;
	base = str_nombre_base.length()? str_nombre_base: str_entrada[0];
	size_t n = base.find_last_of(".");
	if(n != string::npos)
		str_nombre_base = base.substr(0,n);
	n = base.find_last_of("/\\");
	if(n != string::npos)
		str_dir_base = base.substr(0, n+1);
	else
		str_dir_base.clear();
	int max = Entorno->str_incdir.size();
	for(int i=0; i<max; i++) {
		string s = Entorno->str_incdir[i];
		if(s[s.length() - 1] != SEPARADOR)
			Entorno->str_incdir[i] += SEPARADOR;
	}
}

size_t entorno::GetP()
{
	return m->GetP();
}

std::string entorno::GetNombreArchivoActual()
{
	return nombre_archivo_actual;
}

void entorno::SetNombreArchivoActual(std::string _nombre_archivo_actual)
{
	nombre_archivo_actual=_nombre_archivo_actual;
}
